package net.sppan.blog.controller.admin;

import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.IAtom;
import com.jfinal.plugin.activerecord.Page;
import net.sppan.blog.annotation.RequiresPermissions;
import net.sppan.blog.controller.BaseController;
import net.sppan.blog.model.Role;
import net.sppan.blog.model.Settlement;
import net.sppan.blog.model.SettlementApply;
import net.sppan.blog.model.User;
import net.sppan.blog.store.UserStore;
import net.sppan.blog.utils.Const;
import net.sppan.blog.utils.ObjectUtils;
import net.sppan.blog.utils.SimpleDateFormatUtil;
import net.sppan.blog.utils.WebUtils;
import org.apache.poi.hssf.usermodel.*;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.*;
import java.util.Map.Entry;

@RequiresPermissions(key = { "admin:sys:settlement" })
public class AdminSettlementController extends BaseController {

	@RequiresPermissions(key = { "admin:sys:settlement:list" })
	public void list() {

		String searchStatus = getPara("search_status");
		String searchDate = getPara("search_date");
		String searchAgent = getPara("search_agentname");
		String searchId = getPara("search_id");
		User currentUser = WebUtils.currentUser(this);
		Role role = getSessionAttr("loginUserRole");
		int pageNumber = getParaToInt("pageNumber", 1);
		int pageSize = getParaToInt("pageSize", 100);
		String sql = "";
		if (role.getId() == Const.AgentId) {
			sql = " from sys_settlement s where 1=1 and s.agentId=" + currentUser.getId();
			//List<User> agents = User.dao.findUserByRoleId(Const.AgentId);
			//setAttr("agents", agents);
			if (!StrKit.isBlank(searchStatus) && !searchStatus.equals("-1")) {
				setAttr("search_status", searchStatus);
				sql += " and s.status=" + searchStatus;
			}
			if (!StrKit.isBlank(searchAgent) && !searchAgent.equals("0")) {
				setAttr("search_agentname", searchAgent);
				sql += " and s.agentId=" + searchAgent;
			}
			if (!StrKit.isBlank(searchDate)) {
				setAttr("search_date", searchDate);
				String[] ds = searchDate.split(" - ");
				String beginDate = ds[0].replace("-", "");
				String endDate = ds[1].replace("-", "");
				sql += " and s.cleanDay between " + beginDate + " and " + endDate;
			}
			sql += " order by id desc";
			Page<Settlement> page = Settlement.dao.paginate(pageNumber, pageSize, "select s.* ", sql);
			setAttr("pageList", page);
			setAttr("loginUser", currentUser);
			setAttr("loginUserRole", role);
			render("list.html");
		} else {

			//管理员查看的是结算申请表
			sql = " from sys_settlement_apply s  where 1=1 ";

			if (!StrKit.isBlank(searchId)) {
				setAttr("search_id", searchId);
				sql += " and s.id=" + searchId;
			}
			if (!StrKit.isBlank(searchStatus) && !searchStatus.equals("-1")) {
				setAttr("search_status", searchStatus);
				sql += " and s.status=" + searchStatus;
			}
			if (!StrKit.isBlank(searchAgent) && !searchAgent.equals("0")) {
				setAttr("search_agentname", searchAgent);
				sql += " and s.agentId=" + searchAgent;
			}
			if (!StrKit.isBlank(searchDate)) {
				setAttr("search_date", searchDate);
				String[] ds = searchDate.split(" - ");
				String beginDate = ds[0] + " 00:00:00";
				String endDate = ds[1] + " 23:59:59";
				sql += " and s.createTime between '" + beginDate + "' and '" + endDate + "'";
			}
			sql += " order by id desc";
			Page<SettlementApply> page = SettlementApply.dao.paginate(pageNumber, pageSize, "select s.* ", sql);
			setAttr("pageList", page);
			List<User> agents = User.dao.findUserByRoleId(Const.AgentId);
			setAttr("agents", agents);
			render("admin_list.html");
		}
	}

	@RequiresPermissions(key = { "admin:sys:settlement:update" })
	public void update() {
		int id = getParaToInt("id");
		String[] ids = String.valueOf(id).split(",");
		if (ids.length == 1) {
			Settlement settlement = Settlement.dao.findFirst("select s.*,u.name as agentName from sys_settlement s join sys_user u on s.agentId=u.id where s.id=" + id);
			setAttr("settlement", settlement);
			render("update.html");
		} else {

		}
	}

	@RequiresPermissions(key = { "admin:sys:settlement:update" })
	public void batchCheck() {
		BatchSettleBean bean = new BatchSettleBean();
		String id = getPara("id");
		final List<Settlement> list = Settlement.dao.find("select s.* from sys_settlement s where s.id in(" + id + ")");
		if (ObjectUtils.isNotEmpty(list)) {
			Set<Integer> idSet = new HashSet<>();
			Set<Integer> statusSet = new HashSet<>();
			List<Integer> ids = new ArrayList<>();
			List<Integer> days = new ArrayList<>();
			double total = 0D;
			for (Settlement s : list) {
				//判断是否是同一个代理，是否都是未结算状态
				Integer agentId = s.getAgentId();
				Integer status = s.getStatus();
				Integer settlementId = s.getId();
				Integer day = s.getCleanDay();
				ids.add(settlementId);
				days.add(day);
				idSet.add(agentId);
				statusSet.add(status);
				total = ObjectUtils.DoubleAdd(total, s.getAmount());
				s.setStatus(2);
			}
			if (idSet.size() > 1) {
				bean.setSuccess(false);
				bean.setErrMsg("Please choose the same agent");
			} else if (statusSet.contains(1) || statusSet.contains(2)) {
				bean.setSuccess(false);
				bean.setErrMsg("Please choose the new data or refuse data");
			} else {
				Integer agentId = new ArrayList<Integer>(idSet).get(0);
				User agent = User.dao.findById(agentId);
				if (agent != null) {
					final SettlementApply apply = new SettlementApply();
					apply.setAgentId(agentId);
					apply.setAgentName(agent.getName());
					apply.setCreateTime(new Date());
					apply.setStatus(0);
					apply.setDay(ObjectUtils.listToString(days));
					apply.setSettlementIds(ObjectUtils.listToString(ids));
					apply.setAmount(total);
					//写入提现申请表,修改提现表状态
					boolean b = Db.tx(new IAtom() {
						@Override
						public boolean run() {
							try {
								apply.save();
								Db.batchUpdate(list, list.size());
								return true;
							} catch (Exception e) {
								e.printStackTrace();
								return false;
							}
						}
					});
					bean.setErrMsg("apply success");
					bean.setSuccess(b);
				} else {
					bean.setSuccess(false);
					bean.setErrMsg("agent not exists");
				}
			}
		} else {
			bean.setSuccess(false);
			bean.setErrMsg("settlement data not exists");
		}
		renderJson(bean);
	}

	@RequiresPermissions(key = { "admin:sys:settlement:update" })
	public void save() {
		int id = getParaToInt("id");
		int status = getParaToInt("status");
		Settlement settlement = Settlement.dao.findById(id);
		if (settlement != null) {
			settlement.setStatus(status);
			if (status == 1) {
				settlement.setCleanTime(new Date());
			} else {
				settlement.setCleanTime(null);
			}
			settlement.update();
			renderJson(true, "update successfully");
		} else {
			renderJson(false, "update failed");
		}
	}

	@RequiresPermissions(key = { "admin:sys:settlement:list" })
	public void export() {
		String id = getPara("id");
		Map<String, List<Settlement>> map = new HashMap<>();
		Map<String,String> accountMap = new HashMap<>();
		List<SettlementApply> list = SettlementApply.dao.find("select s.* from sys_settlement_apply s where s.id in(" + id + ")");
		if (ObjectUtils.isNotEmpty(list)) {
			for (SettlementApply apply : list) {
				Integer applyId = apply.getId();
				String ids = apply.getSettlementIds();
				String agentName = apply.getAgentName();
				Integer agentId = apply.getAgentId();
				String account = UserStore.instance.getAccountById(agentId+"");
				Double total = apply.getAmount();
				Integer status = apply.getStatus();
				if (status != 0) {
					renderJson(false, "已经处理的结算单不能导出！");
					return;
				}
				List<Settlement> settles = Settlement.dao.find("select * from sys_settlement where id in(" + ids + ")  order by cleanDay asc");
				if (ObjectUtils.isNotEmpty(settles)) {
					List<Settlement> old = map.get(agentName);
					if(ObjectUtils.isNotEmpty(old)){
						settles.addAll(old);
					}
					map.put(agentName, settles);
					accountMap.put(agentName,account);
				}
			}
			//生成Excel
			String excelName = "结算申请单-" + SimpleDateFormatUtil.format(new Date(), SimpleDateFormatUtil.ymd) + ".xls";
			HSSFWorkbook wb = new HSSFWorkbook();
			for (Entry<String, List<Settlement>> entry : map.entrySet()) {
				String key = entry.getKey();
				List<Settlement> settles = entry.getValue();
				HSSFSheet sheet = wb.createSheet(key);
				HSSFCellStyle cellStyleCenter = ExportFileNameUtils.initColumnHeadStyle(wb);//表头样式
				HSSFCellStyle cellStyleRight = ExportFileNameUtils.initColumnCenterstyle(wb);//单元格样式
				HSSFCellStyle cellStyleLeft = ExportFileNameUtils.initColumnCenterstyle(wb);
				cellStyleRight.setAlignment(HSSFCellStyle.ALIGN_RIGHT);//右对齐
				cellStyleLeft.setAlignment(HSSFCellStyle.ALIGN_LEFT);//左对齐
				// 设置列宽
				sheet.setColumnWidth(0, 5000);
				sheet.setColumnWidth(1, 5000);

				HSSFRow row = sheet.createRow(0);
				HSSFCell cell = null;
				cell = row.createCell(0);
				cell.setCellValue("日期");
				cell.setCellStyle(cellStyleCenter);
				cell = row.createCell(1);
				cell.setCellValue("收入");
				cell.setCellStyle(cellStyleCenter);
				int rowNum = 1;
				Double total = 0D;
				for (Settlement settle : settles) {
					row = sheet.createRow(rowNum);
					cell = row.createCell(0);
					cell.setCellValue(settle.getCleanDay());
					cell.setCellStyle(cellStyleCenter);
					cell = row.createCell(1);
					cell.setCellValue(settle.getAmount());
					cell.setCellStyle(cellStyleCenter);
					total = ObjectUtils.DoubleAdd(total, settle.getAmount());
					rowNum++;
				}
				//汇总
				row = sheet.createRow(rowNum);
				cell = row.createCell(1);
				cell.setCellValue(total);
				cell.setCellStyle(cellStyleCenter);
				rowNum++;
				row = sheet.createRow(rowNum);
				cell = row.createCell(0);
				cell.setCellValue(accountMap.get(key)==null?"":accountMap.get(key));
				cell.setCellStyle(cellStyleCenter);
			}
			try {
				ByteArrayOutputStream os = new ByteArrayOutputStream();
				wb.write(os);
				byte[] fileContent = os.toByteArray();
				ByteArrayInputStream is = new ByteArrayInputStream(fileContent);
				getResponse().setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(excelName, "UTF-8"));
				OutputStream out = getResponse().getOutputStream();
				//创建缓冲区
				byte buffer[] = new byte[1024];
				int len = 0;
				//循环将输入流中的内容读取到缓冲区当中
				while ((len = is.read(buffer)) > 0) {
					//输出缓冲区的内容到浏览器，实现文件下载
					out.write(buffer, 0, len);
				}
				//关闭文件输入流
				is.close();
				//关闭输出流
				out.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		} else {
			renderJson(false, "导出的结算单原始结算数据不存在！");
			return;
		}
		renderNull();
		return;
	}

	public static class BatchSettleBean {
		private boolean success;
		private String errMsg;
		private Settlement settleMent;

		public boolean isSuccess() {
			return success;
		}

		public void setSuccess(boolean success) {
			this.success = success;
		}

		public String getErrMsg() {
			return errMsg;
		}

		public void setErrMsg(String errMsg) {
			this.errMsg = errMsg;
		}

		public Settlement getSettleMent() {
			return settleMent;
		}

		public void setSettleMent(Settlement settleMent) {
			this.settleMent = settleMent;
		}

	}

	@RequiresPermissions(key = { "admin:sys:settlement:update" })
	public void updateStatus() {
		String id = getPara("id");
		final String status = getPara("status");
		final String reason = getPara("reason");
		final SettlementApply apply = SettlementApply.dao.findById(id);
		if (apply != null) {
			String ids = apply.getSettlementIds();
			final List<Settlement> list = Settlement.dao.find("select * from sys_settlement where id in(" + ids + ")");
			if (ObjectUtils.isNotEmpty(list)) {
				for (Settlement settle : list) {
					Integer settleStatus = settle.getStatus();
					if ("1".equals(status)) {
						settleStatus = 1;
					} else if ("2".equals(status)) {
						settleStatus = 3;
					}
					settle.setStatus(settleStatus);
					settle.setReason(reason);
					settle.setCleanTime(new Date());
				}
				boolean b = Db.tx(new IAtom() {
					@Override
					public boolean run() {
						try {
							apply.setStatus(Integer.parseInt(status));
							apply.setReason(reason);
							apply.setUpdateTime(new Date());
							apply.update();
							Db.batchUpdate(list, list.size());
							return true;
						} catch (Exception e) {
							e.printStackTrace();
							return false;
						}
					}
				});
				renderJson(b, "operation success");
				return;
			}
		}
		renderJson(false, "operation failed");
	}
}
